package com.budwk.app.sqfwV2.generator.dayingRoadExcel;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import com.alibaba.fastjson.JSONObject;
import com.budwk.app.sqfw.component.CommonComponent;
import com.budwk.app.sqfw.constants.CommonConstants;
import com.budwk.app.sqfw.constants.DictConstants;
import com.budwk.app.sqfw.models.Sqfw_formSummary_new;
import com.budwk.app.sqfwDoc.bo.SqfwExcelForSummaryBO;
import com.budwk.app.sqfwDoc.bo.SqfwExcelJudgeRes;
import com.budwk.app.sqfwDoc.codeGenerator.excelGenerate.BaseExcelParamDTO;
import com.budwk.app.sqfwDoc.codeGenerator.excelGenerate.BaseTemplateExcelGenerator;
import com.budwk.app.sqfwDoc.codeGenerator.excelGenerate.SqfwExcelCreateCommonBO;
import com.budwk.app.sqfwV2.component.DayingRoadPdfComponent;
import com.budwk.app.sqfwV2.component.ProblemComponent;
import com.budwk.app.sqfwV2.dto.dto.FireSafetyOnDayingRoadPdfDTO;
import com.budwk.app.sqfwV2.dto.dto.centuryCity.SafeCheckTaskParamDataDTO;
import com.budwk.app.sqfwV2.dto.dto.dayingRoad.template.ThreeDetailedExcelVo;
import com.budwk.app.sqfwV2.dto.image.FireSafetyOnDayingRoadExcelImageConfigBO;
import com.budwk.app.sqfwV2.enums.DayingRoadFileServiceEnum;
import com.budwk.app.sys.models.Sys_user;
import com.budwk.app.sys.services.SysUserService;
import com.budwk.app.util.StrUtil;
import com.budwk.app.util.poiUtils.CommonFormOfficeUtils;
import com.budwk.app.util.poiUtils.excelPictureConfigBO.ExcelFileCreateParamBO;
import com.budwk.app.util.poiUtils.nutzBeanUtils.NutzIocUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.time.*;
import java.util.*;

/**
 * 安全隐患“三清单”/Excle
 */

@Slf4j
public class ThreeDetailedGenerator extends BaseTemplateExcelGenerator implements DayingRoadExcelGenerator {

    @Override
    protected String getTemplateName() {
        return DayingRoadFileServiceEnum.DAYING_ROAD_EXCEL_SAFE.getFilePath();
    }

    /**
    * 可以参照 {@link com.budwk.app.sqfw.enums.DownLoadFileNameEnum}
    *
    * @return 文件名名称
    */
    @Override
    public String getDownloadFileName() {
        //TODO 在这里返回你生成的文件名名称，注意注意注意不用带上后缀
        return DayingRoadPdfComponent.getDictName(DayingRoadFileServiceEnum.DAYING_ROAD_EXCEL_SAFE.getCode(), null);
    }

    /**
     * 用户自定义excel基础参数，比如表头这样的公用数据
     * @param excelParam 已经填充的基础数据据
     * @param excelCreateParam excel生成提供的原料
     */
    @Override
    protected void customerPopularSheetBaseParam(Map<String, Object> excelParam, SqfwExcelCreateCommonBO excelCreateParam) {
        log.info("ThreeDetailedGenerator getBaseExcelParamDTO: {}", JSONObject.toJSONString(excelCreateParam.getBaseExcelParamDTO()));
        SysUserService userService = NutzIocUtils.getBean(SysUserService.class);
        Sys_user user = userService.fetch(excelCreateParam.getBaseExcelParamDTO().getCreateUserId());
        // 大营路街道安全隐患“三清单”     居委会取值只取街道+社区，当社区=直属时，只显示街道名称
        BaseExcelParamDTO b = excelCreateParam.getBaseExcelParamDTO();
        excelParam.put("unitName", DayingRoadPdfComponent.getUnitName(b));
        excelParam.put("fillUserName", b.getCreateUserName());
        excelParam.put("phone", user.getMobile());
        excelParam.put("fillUserNamePhone", user.getUsername() + "-" + user.getMobile());
        excelParam.put("downloadDate", DateUtil.format(new Date(), DatePattern.NORM_DATETIME_PATTERN));
    }

    @Override
    protected void customerPopularSheetDataParam(List<Map<String, Object>> listMap, SqfwExcelCreateCommonBO excelCreateParam) {
        List<Sqfw_formSummary_new> summaryList = DayingRoadPdfComponent.getSummaryList(listMap, excelCreateParam);
        log.info("ThreeDetailedGenerator customerDataParam summaryList:  {}", JSONObject.toJSONString(summaryList));
        int num = 1;
        for (Sqfw_formSummary_new summary : summaryList) {
            FireSafetyOnDayingRoadPdfDTO roadPdfDTO = JSONObject.parseObject(summary.getParamData(), FireSafetyOnDayingRoadPdfDTO.class);
            log.info("ThreeDetailedGenerator customerDataParam roadPdfDTO: {}", JSONObject.toJSONString(roadPdfDTO));
            // 构建数据
            Map<String, Object> map = buildExcelMap(roadPdfDTO, summary);
            if (map != null) {
                map.put("num", num ++);
                listMap.add(map);
            }

        }
        log.info("ThreeAndOneSiteGenerator customerDataParam end: {}", JSONObject.toJSONString(listMap));
    }

    private ThreeDetailedExcelVo buildBaseInfo(FireSafetyOnDayingRoadPdfDTO roadPdfDTO, Sqfw_formSummary_new summary) {
        ThreeDetailedExcelVo excelVo = new ThreeDetailedExcelVo();
        // 行业领域
        List<String> names = DayingRoadPdfComponent.getIndustrySectorStr(roadPdfDTO.getIndustrySector());
        // 2 居委会
        String communityStr = "";
        String community = summary.getCommunity();
        if (StringUtils.isNotBlank(community)) communityStr = community.replace("社区", "居委会");
        excelVo.setIndustrySector(String.join(",", names))
                .setCommunityStr(communityStr)
                .setAddress(StrUtil.replaceNullStr(roadPdfDTO.getAddress()))
                .setOperator(StrUtil.replaceNullStr(roadPdfDTO.getOperator()))
                .setCreateUsername(summary.getCreateUserName())
                .setPlaceName(StrUtil.replaceNullStr(roadPdfDTO.getPlaceName()));
        return excelVo;
    }

    private Map<String, Object> buildExcelMap(FireSafetyOnDayingRoadPdfDTO roadPdfDTO, Sqfw_formSummary_new summary) {
        Boolean isExistDanger = roadPdfDTO.getIsExistDanger();
        if (!isExistDanger) {
            return null;
        }
        List<SafeCheckTaskParamDataDTO> fireIssues = ProblemComponent.getFireIssues(roadPdfDTO);
        if (fireIssues.size() == 0) {
            return null;
        }
        // 1 构建基本信息
        ThreeDetailedExcelVo excelVo = buildBaseInfo(roadPdfDTO, summary);
        // 3 整改时间
        // 如果全部是立即整改 则取提交时间 并且消防问题取上次的数据
        LocalDate rectificationDate = roadPdfDTO.getRectificationDate();
        long count = fireIssues.stream().filter(e -> e.getIsRectification().equals(false)).count();
        // 隐患内容
        excelVo.setFireIssues(buildFireIssues(roadPdfDTO.getExistDangerStr()));
        if (count == 0) {
            rectificationDate = summary.getCreateDate().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        }
        excelVo.setRectifyingDangersMeasures(StrUtil.replaceNullStr(roadPdfDTO.getRectifyingDangersMeasures()));
        // 整改时限
        LocalDateTime createTime = summary.getCreateDate().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
        LocalDateTime inspectionDate = roadPdfDTO.getInspectionDate() == null ? createTime : roadPdfDTO.getInspectionDate();
        if (rectificationDate == null) {
            rectificationDate = summary.getCreateDate().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        }
        excelVo.setRectificationStr(calRectificationDeadline(rectificationDate, inspectionDate, excelVo));
        // 旅馆时 整改时间为-
        if (DictConstants.INDUSTY_SECTOR_HOTEL.equals(roadPdfDTO.getIndustrySector())) {
            excelVo.setRectificationDateStr(CommonConstants.HORIAONTAL_LINE);
        }
        excelVo.setRectificationDateStr(LocalDateTimeUtil.format(rectificationDate, "yyyy年MM月dd日"));
        Map<String, Object> map = CommonComponent.entityToMap(excelVo);
        // 图片
        map.put("violationPhoto", new ArrayList<>());
        Optional<SafeCheckTaskParamDataDTO> optional = fireIssues.stream().filter(e -> StringUtils.isNotEmpty(e.getRiskImages())).findFirst();
        if (optional.isPresent()) {
            SafeCheckTaskParamDataDTO safeCheckTaskParamDataDTO = optional.get();
            map.put("violationPhoto", CommonFormOfficeUtils.addPictureToByteList(safeCheckTaskParamDataDTO.getRiskImages(), 1));
        }
        map.put("rectificationAfterPhoto", new ArrayList<>());
        Optional<SafeCheckTaskParamDataDTO> optional1 = fireIssues.stream().filter(e -> StringUtils.isNotEmpty(e.getRectificationBackPhoto())).findFirst();
        if (optional1.isPresent()) {
            SafeCheckTaskParamDataDTO safeCheckTaskParamDataDTO = optional1.get();
            map.put("rectificationAfterPhoto", CommonFormOfficeUtils.addPictureToByteList(safeCheckTaskParamDataDTO.getRectificationBackPhoto(), 1));
        }
        return map;
    }

    private String buildFireIssues(String existDangerStr) {
        log.info("buildFireIssues start : {}", existDangerStr);
        if (StringUtils.isEmpty(existDangerStr)) {
            return CommonConstants.HORIAONTAL_LINE;
        }
        // 取出特殊字符 话术模板：已责令场所负责人员，将+问题进行整改，并进行口头教育
        String existDangerStr1 = existDangerStr.replace("已责令场所负责人员，将", "");
        String existDangerStr2 = existDangerStr1.replace("问题进行整改，并进行口头教育", "");
        String existDangerStr3 = existDangerStr2.replace("，并进行口头教育", "");
        log.info("buildFireIssues end : {}", existDangerStr3);
        return existDangerStr3;
    }

    /**
     * 计算整改时限
     * @param rectificationDate
     * @param inspectionDate
     * @return
     */
    public static String calRectificationDeadline(LocalDate rectificationDate, LocalDateTime inspectionDate, ThreeDetailedExcelVo excelVo) {
        if (rectificationDate == null) {
            return null;
        }
        // 没有整改 检查时间
        inspectionDate = inspectionDate == null ? LocalDateTime.now() : inspectionDate;
        String rectificationStr = "";
        Duration between = LocalDateTimeUtil.between(inspectionDate, rectificationDate.atTime(LocalTime.now()));
        long days = between.toDays();
        if (days == 0) {
            rectificationStr = "已当天整改";
            excelVo.setRemark("已整改");
        } else {
            rectificationStr = days + "天";
            excelVo.setRemark("未整改");
        }
        return rectificationStr;
    }

    /**
     * ●生成表格注意事项：
     * ○当之前的【a24】有值时，生成表格。
     * ○如果【a60】的第六个数组或第七个数组有值，则生成表格。
     * ○如果【a61】的第六个数组或第七个数组有值，则生成表格。
     * @param roadPdfDTO
     * @return
     */
    public boolean isGenerateExcel(FireSafetyOnDayingRoadPdfDTO roadPdfDTO) {
//        // 判断a5是否为重点场所 选择重点场所 不生成表格
        if (DayingRoadPdfComponent.isKeyLocations(roadPdfDTO)) {
            return false;
        }
        Boolean isExistDanger = roadPdfDTO.getIsExistDanger();
        if (isExistDanger != null) {
            return isExistDanger;
        }
        return true;
    }

    @Override
    protected void completeExcelFileCreateParam(ExcelFileCreateParamBO excelFileCreateParam) {

    }

    @Override
    protected void customerPopularRowDataMap(Map<String, Object> rowDataMap, SqfwExcelForSummaryBO forSummaryBO) {

    }

    /**
     * 如果在遍历之前就能够判断excel是否生成，那么就在这个方法中进行判断
     * @param excelCreateParam excel生成所需的最为全面的数据
     * @param excelParam excel已经填充的部分数据
     */
    @Override
    protected SqfwExcelJudgeRes judgeDataIntoExcelBeforeErgodic(SqfwExcelCreateCommonBO excelCreateParam, Map<String, Object> excelParam) {
        return DayingRoadPdfComponent.getSqfwExcelJudgeRes(excelCreateParam, new ThreeDetailedGenerator());
    }

    /**
     * 如果在遍历之后能够判断excel是否生成，那么就在这个方法中进行判断
     * @param excelParam excel已经填充的部分数据
     */
    @Override
    protected SqfwExcelJudgeRes judgeDataIntoExcelBeforeCreate(Map<String, Object> excelParam) {
        return null;
    }

    @Override
    protected Class<?> getImageConfigBO() {
        return FireSafetyOnDayingRoadExcelImageConfigBO.class;
    }
}
